#pragma once

#include <buddy_allocator.hpp>
#include <mutex>
#include <list>
#include <bitset>
#include <memory>


class MemoryAllocator
{
public:
    MemoryAllocator(const MemoryAllocator &) = delete;
    MemoryAllocator(MemoryAllocator &&) = delete;
    MemoryAllocator &operator=(const MemoryAllocator &) = delete;
    MemoryAllocator &operator=(MemoryAllocator &&) = delete;

    static MemoryAllocator &instance()
    {
        static std::once_flag flag;
        std::call_once(flag, [&]() { // note: make_unique不能使用子类构造父类，需要显式 new 裸指针
            impl_ = std::unique_ptr<MemoryPoolImpl>(new BuddyAllocator());
        });
        static MemoryAllocator allocator;
        return allocator;
    }

    /// @brief 分配n个字节的MemoryBlock
    /// @param n
    /// @return 分配的block
    MemoryChunk allocate(std::size_t n);

    /// @brief 释放block
    /// @param block
    void deallocate(MemoryChunk &chunk);

    ~MemoryAllocator() = default;

private:
    MemoryAllocator() = default;

private:
    static std::unique_ptr<MemoryPoolImpl> impl_;
};